#include <stdio.h>              // 用于输入输出函数
#include <string.h>             // 用于字符串处理函数
#include <openssl/aes.h>        // 包含 AES 加密/解密函数的头文件
#include <openssl/rand.h>       // 包含随机数生成函数的头文件

// 错误处理函数
void handleErrors(void)
{
    ERR_print_errors_fp(stderr); // 打印错误信息到标准错误输出
    abort();                     // 终止程序
}

// 打印十六进制格式的字符串
void printHex(const unsigned char *s, int len)
{
    for (int i = 0; i < len; i++) {
        printf("%02x", s[i]);    // 以十六进制格式打印每个字节
    }
    printf("\n");                // 换行
}

// AES 加密函数
void aes_encrypt(const unsigned char *key, const unsigned char *plaintext, unsigned char *ciphertext)
{
    AES_KEY encryptKey;           // 定义 AES 密钥结构体
    unsigned char iv[AES_BLOCK_SIZE]; // 定义初始化向量 (IV)
    memset(iv, 0, AES_BLOCK_SIZE);    // 将 IV 初始化为零

    // 设置加密密钥
    if (AES_set_encrypt_key(key, 128, &encryptKey) < 0)
        handleErrors();           // 如果设置失败，处理错误

    // 执行 AES CBC 模式加密
    AES_cbc_encrypt(plaintext, ciphertext, strlen((const char *)plaintext) + 1, &encryptKey, iv, AES_ENCRYPT);
}

// AES 解密函数
void aes_decrypt(const unsigned char *key, const unsigned char *ciphertext, unsigned char *plaintext)
{
    AES_KEY decryptKey;           // 定义 AES 密钥结构体
    unsigned char iv[AES_BLOCK_SIZE]; // 定义初始化向量 (IV)
    memset(iv, 0, AES_BLOCK_SIZE);    // 将 IV 初始化为零

    // 设置解密密钥
    if (AES_set_decrypt_key(key, 128, &decryptKey) < 0)
        handleErrors();           // 如果设置失败，处理错误

    // 执行 AES CBC 模式解密
    AES_cbc_encrypt(ciphertext, plaintext, strlen((const char *)ciphertext), &decryptKey, iv, AES_DECRYPT);
}

int main(void)
{
    // 16 字节的密钥，适用于 AES-128
    unsigned char key[] = "0123456789abcdef"; // 示例密钥

    // 示例明文
    unsigned char plaintext[] = "Hello, OpenSSL AES!";
    unsigned char ciphertext[128] = {};          // 存储加密结果的数组
    unsigned char decryptedtext[128] = {};       // 存储解密结果的数组

    printf("Plaintext: %s\n", plaintext);       // 打印原始明文

    // 进行加密
    aes_encrypt(key, plaintext, ciphertext);     // 调用 AES 加密函数
    printf("Ciphertext: ");                      // 打印加密后的结果
    printHex(ciphertext, strlen((const char *)plaintext) + 1); // 以十六进制格式打印密文

    // 进行解密
    aes_decrypt(key, ciphertext, decryptedtext); // 调用 AES 解密函数
    printf("Decrypted text: %s\n", decryptedtext); // 打印解密后的结果

    return 0;               // 程序正常结束
}
